/*
 * Copyright 2010, David George, Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.magneato.dao;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.magneato.dto.Page;
import org.magneato.service.FileUploader;

public class FTPUploader implements FileUploader {
	/** The URL connection object */
	private URLConnection m_client;

	/** The FTP host/server to be connected */
	private String host;

	/** The FTP user */
	private String user;

	/** The FTP user’s password */
	private String password;

	/** The remote file that needs to be uploaded or downloaded */
	private String remoteFile;

	/** The previous error message triggered after a method is called */
	private String erMesg;

	/** The previous success message after any method is called */
	private String succMesg;

	/**
	 * Setter method for the remote file, this must include the sub-directory
	 * path relative to the user’s home directory, e.g you’e going to download a
	 * file that is within a sub directory called “sdir”, and the file is named
	 * “d.txt”, so you shall include the path as “sdir/d.txt”
	 */
	public void setRemoteFile(String d) {
		this.remoteFile = d;
	}

	/**
	 * Upload a file to a FTP server. A FTP URL is generated with the following
	 * syntax: ftp://user:password@host:port/filePath;type=i.
	 * 
	 * @param ftpServer
	 *            , FTP server address (optional port ':portNumber').
	 * @param user
	 *            , Optional user name to login.
	 * @param password
	 *            , Optional password for user.
	 * @param fileName
	 *            , Destination file name on FTP server (with optional preceding
	 *            relative path, e.g. "myDir/myFile.txt").
	 * @param source
	 *            , Source file to upload.
	 * @throws MalformedURLException
	 */
	public String upload(File srcFile, String destDir, Page page) {

		StringBuffer sb = new StringBuffer("ftp://");
		// check for authentication else assume its anonymous access.
		if (user != null && password != null) {
			sb.append(user);
			sb.append(':');
			sb.append(password);
			sb.append('@');
		}
		sb.append(host);
		sb.append('/');
		sb.append(remoteFile);
		/*
		 * type ==> a=ASCII mode, i=image (binary) mode, d= file directory
		 * listing
		 */
		sb.append(";type=i");

		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			URL url = new URL(sb.toString());
			URLConnection urlc = url.openConnection();

			bos = new BufferedOutputStream(urlc.getOutputStream());
			bis = new BufferedInputStream(new FileInputStream(srcFile));

			int i;
			// read byte by byte until end of stream
			while ((i = bis.read()) != -1) {
				bos.write(i);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		} finally {
			if (bis != null)
				try {
					bis.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			if (bos != null)
				try {
					bos.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
		}
		return "";
	}

	/**
	 * Download a file from a FTP server. A FTP URL is generated with the
	 * following syntax: ftp://user:password@host:port/filePath;type=i.
	 * 
	 * @param ftpServer
	 *            , FTP server address (optional port ':portNumber').
	 * @param user
	 *            , Optional user name to login.
	 * @param password
	 *            , Optional password for user.
	 * @param fileName
	 *            , Name of file to download (with optional preceeding relative
	 *            path, e.g. one/two/three.txt).
	 * @param destination
	 *            , Destination file to save.
	 * @throws MalformedURLException
	 *             , IOException on error.
	 */
	public void download(String ftpServer, String user, String password,
			String fileName, File destination) throws MalformedURLException,
			IOException {
		if (ftpServer != null && fileName != null && destination != null) {
			StringBuffer sb = new StringBuffer("ftp://");
			// check for authentication else assume its anonymous access.
			if (user != null && password != null) {
				sb.append(user);
				sb.append(':');
				sb.append(password);
				sb.append('@');
			}
			sb.append(ftpServer);
			sb.append('/');
			sb.append(fileName);
			/*
			 * type ==> a=ASCII mode, i=image (binary) mode, d= file directory
			 * listing
			 */
			sb.append(";type=i");
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;
			try {
				URL url = new URL(sb.toString());
				URLConnection urlc = url.openConnection();

				bis = new BufferedInputStream(urlc.getInputStream());
				bos = new BufferedOutputStream(new FileOutputStream(
						destination.getName()));

				int i;
				while ((i = bis.read()) != -1) {
					bos.write(i);
				}
			} finally {
				if (bis != null)
					try {
						bis.close();
					} catch (IOException ioe) {
						ioe.printStackTrace();
					}
				if (bos != null)
					try {
						bos.close();
					} catch (IOException ioe) {
						ioe.printStackTrace();
					}
			}
		} else {
			System.out.println("Input not available");
		}
	}

	// Injected by Spring
	/** Setter method for the FTP host/server */
	public void setHost(String host) {
		this.host = host;
	}

	/** Setter method for the FTP user */
	public void setUser(String user) {
		this.user = user;
	}

	/** Setter method for the FTP user’s password */
	public void setPassword(String p) {
		this.password = p;
	}

	@Override
	public int deleteAttachments(Page page) throws IOException {
		// TODO Auto-generated method stub
		return 0;
	}
}